home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / vbdatabs / hash.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-17  |  5.4 KB  |  192 lines

  1. // ------------------------------- //
  2. // -------- Start of File -------- //
  3. // ------------------------------- //
  4. // ----------------------------------------------------------- // 
  5. // C++ Source Code File Name: hash.cpp 
  6. // Compiler Used: MSVC40, DJGPP 2.7.2.1, GCC 2.7.2.1, HP CPP 10.24
  7. // Produced By: Doug Gaer
  8. // File Creation Date: 02/14/1996 
  9. // Date Last Modified: 03/17/1999
  10. // ----------------------------------------------------------- // 
  11. // ------------- Program description and details ------------- // 
  12. // ----------------------------------------------------------- // 
  13. /*
  14. THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
  15. THE ENTIRE RISK OF THE QUALITY AND PERFORMANCE OF THIS SOFTWARE
  16. IS WITH YOU. SHOULD ANY ELEMENT OF THIS SOFTWARE PROVE DEFECTIVE,
  17. YOU WILL ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR
  18. CORRECTION.
  19.  
  20. The following program uses the class implementation of a symbol
  21. table using a hashed lookup.
  22. */
  23. // ----------------------------------------------------------- // 
  24. #include <string.h>
  25.  
  26. class TableData
  27. {
  28. public:
  29.   TableData() { Next = 0; Data = 0; }
  30.  
  31. public:
  32.   char *GetData() { return Data; } 
  33.   
  34. public:
  35.   char *Data;
  36.   TableData *Next;
  37. };
  38.  
  39. class HashTable : public TableData
  40. {
  41. public:
  42.   HashTable(unsigned sz = 15);
  43.   ~HashTable() { Clear(); }
  44.  
  45. private:
  46.   HashTable(const HashTable &ob) { }      // Disallow copying
  47.   void operator=(const HashTable &ob) { } // Disallow assignment
  48.  
  49. public:
  50.   TableData *Find(char *str); 
  51.   TableData *Insert(char *str);
  52.   int GetHashCode(char *str);
  53.   void Clear();
  54.   
  55. private:
  56.   TableData **tbl;
  57.   unsigned size;
  58. };
  59.  
  60. HashTable::HashTable(unsigned sz)
  61. {
  62.   if (sz < 0) sz = 15; // Do not allow a negitive table size
  63.   tbl = new TableData *[size = sz]; 
  64.   for (unsigned i = 0; i < sz; i++) tbl[i] = 0; // Null all the table nodes
  65. }
  66.  
  67. void HashTable::Clear()
  68. // Delete all the table nodes and release memory back to the heap
  69.   for(unsigned i = 0; i < size; i++)
  70.     {
  71.       TableData *buf = Next;
  72.       for(TableData *ptr = tbl[i]; ptr; ptr = buf)
  73.     {
  74.       buf = ptr->Next;    // Save next link before deleting it
  75.       ptr->Next = 0;      // Null the Next pointer
  76.       tbl[i] = ptr->Next; // Release node before deleting pointer holding
  77.       delete ptr->Data;   
  78.       delete ptr;
  79.     }
  80.     }
  81. }
  82.  
  83. int HashTable::GetHashCode(char *str)
  84. {
  85.   // Obtain a valid hash code for the table data
  86.   int ii = 0;  // ii will represent the hash code
  87.   char *pp = str;
  88.   // Add each character of string p to ii using an exclusive OR
  89.   while (*pp) ii = ii<<1 ^ *pp++;  // Shift left to avoid using only 1 byte
  90.   if (ii < 0) ii = -ii; // Negate if less then zero
  91.   ii %= size; // Divide with remainder and assign
  92.  
  93.   return ii;
  94. }
  95.  
  96. TableData *HashTable::Find(char *str)
  97. // Search the table for a matching node
  98. {
  99.   int ii = GetHashCode(str);
  100.   
  101.   // Search the table for the p string
  102.   for (TableData *n = tbl[ii]; n; n = n->Next)
  103.       if (strcmp(str, n->Data) == 0) return n;
  104.  
  105.   // Return a NULL if not found 
  106.   return 0;
  107. }
  108.  
  109. TableData *HashTable::Insert(char *str)
  110. // Insert a new node into the table
  111. {
  112.   int ii = GetHashCode(str);
  113.   
  114.   TableData *nn = new TableData;
  115.   nn->Data = new char[strlen(str)+1]; // Allocate memory for the string
  116.   strcpy(nn->Data,str); // Copy data into memory location
  117.  
  118.   if(tbl[ii] == 0) {
  119.     // First node in the table
  120.     tbl[ii] = nn;
  121.     return nn;
  122.   }
  123.   else {
  124.     // Next node in the table
  125.     nn->Next = tbl[ii]; // Update Next pointer  
  126.     tbl[ii] = nn;       // New node is now the at head of the table 
  127.     return nn;
  128.   }
  129.  
  130.   return 0; // Return 0 if Insert function fails
  131. }
  132.  
  133. // Test program code starts here
  134. // *********************************************************** //
  135. #include <iostream.h>
  136. #include <ctype.h>
  137.  
  138. // Create an array of items to load in the hash table
  139. const int Items = 5; // Adjust this number if any more items are added
  140. char *TblData[Items] = { "BIRD", "CAT", "COW", "DOG", "SNAKE" };
  141.  
  142. main()
  143. {
  144.   HashTable Table(Items);
  145.   TableData *ptr;
  146.   char buf[255];
  147.   const char *ExitCode = "EXIT";
  148.   
  149.   // Add the entries to the hash table
  150.   for(int Count = 0; Count < Items; Count++)
  151.   {
  152.     // Exit loop if Items is greater then the number of array elements  
  153.     if(TblData[Count] == 0) break;
  154.     ptr = Table.Insert(TblData[Count]);
  155.   }
  156.  
  157.   cout << "Enter the name of an animal to search for at the prompt." << endl;
  158.   cout << "Enter EXIT to exit the program." << endl;
  159.   
  160.   do // Loop on the users input
  161.     {
  162.       cout << endl;
  163.       cout << "Enter the name of an animal -> ";
  164.       cin.getline(buf, sizeof(buf)); 
  165.       cout << endl;
  166.  
  167.       // Convert all entries to upper case
  168.       for(int i = 0; (buf[i] != ' ') && (buf[i] != '\0'); i++)
  169.     buf[i] = toupper(buf[i]);
  170.  
  171.       if (strcmp(buf, ExitCode) == 0) break; // Break out of the loop
  172.       
  173.       cout << "Searching the table for a possible match..." << endl;
  174.       ptr = Table.Find(buf);
  175.       if(ptr)
  176.     cout << "Found: " << ptr->GetData() << " in the hash table." << endl;
  177.       else
  178.     cout << "Did not find: " << buf << " in the hash table." << endl;
  179.  
  180.     }while(cin); // Test cin for each pass through the loop
  181.  
  182.   Table.Clear();
  183.   
  184.   return 0;
  185. }
  186. // ----------------------------------------------------------- // 
  187. // ------------------------------- //
  188. // --------- End of File --------- //
  189. // ------------------------------- //
  190.  
  191.